package fisco;

import org.fisco.bcos.sdk.BcosSDK;
import org.fisco.bcos.sdk.abi.FunctionReturnDecoder;
import org.fisco.bcos.sdk.abi.TypeReference;
import org.fisco.bcos.sdk.abi.datatypes.Utf8String;
import org.fisco.bcos.sdk.abi.datatypes.DynamicArray;
import org.fisco.bcos.sdk.abi.datatypes.generated.Int256;
import org.fisco.bcos.sdk.abi.datatypes.generated.Uint256;
import org.fisco.bcos.sdk.client.Client;
import org.fisco.bcos.sdk.client.protocol.response.BcosTransactionReceipt;
import org.fisco.bcos.sdk.client.protocol.response.TransactionReceiptWithProof;
import org.fisco.bcos.sdk.client.protocol.response.TransactionReceiptWithProof.ReceiptAndProof;
import org.fisco.bcos.sdk.config.ConfigOption;
import org.fisco.bcos.sdk.crypto.CryptoSuite;
import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
import org.fisco.bcos.sdk.crypto.keypair.ECDSAKeyPair;
import org.fisco.bcos.sdk.crypto.keystore.KeyTool;
import org.fisco.bcos.sdk.crypto.keystore.PEMKeyStore;
import org.fisco.bcos.sdk.model.CryptoType;
import org.fisco.bcos.sdk.model.TransactionReceipt;
import org.fisco.bcos.sdk.transaction.codec.decode.TransactionDecoderInterface;
import org.fisco.bcos.sdk.transaction.codec.decode.TransactionDecoderService;
import org.fisco.bcos.sdk.transaction.manager.AssembleTransactionProcessor;
import org.fisco.bcos.sdk.transaction.manager.TransactionProcessorFactory;
import org.fisco.bcos.sdk.transaction.model.dto.TransactionResponse;
import org.fisco.bcos.sdk.utils.Numeric;
import org.fisco.bcos.web3j.tx.txdecode.ResultEntity;
import org.fisco.bcos.web3j.tx.txdecode.TransactionDecoder;
import org.junit.Test;

import java.math.BigInteger;
import java.security.KeyPair;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static org.fisco.bcos.web3j.tx.txdecode.TransactionDecoderFactory.buildTransactionDecoder;

public class demotest {
    public final String configFile = "src/main/resources/config-example.toml";
    @Test
    public void test() throws Exception {
        // 初始化BcosSDK对象
//        ConfigOption configOption = BcosSDK.build(configFile);
        BcosSDK sdk = BcosSDK.build(configFile);
        // 获取Client对象，此处传入的群组ID为1
        Client client = sdk.getClient(Integer.valueOf(1));
        System.out.println( client);
        // 构造AssembleTransactionProcessor对象，需要传入client对象，CryptoKeyPair对象和abi、binary文件存放的路径。abi和binary文件需要在上一步复制到定义的文件夹中。
//        CryptoKeyPair keyPair = client.getCryptoSuite().createKeyPair();
        //使用注入私钥，确定用户。
        //通过cLient获取cryptoSuite对象
//        CryptoSuite cryptoSuite = client.getCryptoSuite();
//        //加载pem文件
//        cryptoSuite.loadAccount("pem","https://ncp-sy-databasement.oss-cn-qingdao.aliyuncs.com/ncp-fisco/0x5fa6fd086f00ed0ef31dfb4a0ec020523cd6183c68c7bb1c85e09dba338e8b49.pem",null);
        //进行文件解析


//        KeyTool keyTool = new PEMKeyStore("https://ncp-sy-databasement.oss-cn-qingdao.aliyuncs.com/ncp-fisco/0x5fa6fd086f00ed0ef31dfb4a0ec020523cd6183c68c7bb1c85e09dba338e8b49.pem");
//        KeyPair keyPair1 = keyTool.getKeyPair();
//        CryptoSuite cryptoSuite = new CryptoSuite(CryptoType.ECDSA_TYPE);
//        CryptoKeyPair keyPair = cryptoSuite.createKeyPair(keyPair1);
        ECDSAKeyPair ecdsaKeyPair = new ECDSAKeyPair();
        CryptoKeyPair keyPair = ecdsaKeyPair.createKeyPair("49afa5afc0dbfc5b7f87bc7c39de9e3c4b791098be63729684364cdc0070c56c");

        AssembleTransactionProcessor transactionProcessor = TransactionProcessorFactory.createAssembleTransactionProcessor(client, keyPair, "src/main/resources/abi/", "");
        // 创建调用交易函数的参数，此处为传入一个参数
        List<Object> params = new ArrayList<>();
        String pesticide_crop_id = "hzb";
        String crop_event_id = "2";
        String pesticide_id = "zhangtaiyu";
        String pesticide_name = "application_date";
        params.add(pesticide_crop_id);
        params.add(crop_event_id);
        params.add(pesticide_id);
        params.add(pesticide_name);
        // 调用HelloWorld合约，合约地址为helloWorldAddress， 调用函数名为『set』，函数参数类型为params
        TransactionResponse transactionResponse = transactionProcessor.sendTransactionAndGetResponseByContractLoader("CropPesticideContract", "0x8c6cb0720e40b0ff9f8eaf6da01a409dd84b4cd2", "insert", params);
        List<Object> result = transactionResponse.getReturnObject();

        //获取交易哈希
        String transactionHash = transactionResponse.getTransactionReceipt().getTransactionHash();
        System.out.println(transactionHash);
        //获取交易总数
//        String  txNumber = client.getTotalTransactionCount().getTotalTransactionCount().getTxSum();
//        int startTxNumber = Integer.parseInt(txNumber.replace("0x",""), 16);


        if(result != null){
            for (Object object : result) {
                System.out.println(object.toString());
            }
        }
       }
    @Test
    public void test2() throws Exception{
           // 初始化BcosSDK对象
//         ConfigOption configOption = BcosSDK.build(configFile);
           BcosSDK sdk = BcosSDK.build(configFile);
           // 获取Client对象，此处传入的群组ID为1
           Client client = sdk.getClient(Integer.valueOf(1));
           // 构造AssembleTransactionProcessor对象，需要传入client对象，CryptoKeyPair对象和abi、binary文件存放的路径。abi和binary文件需要在上一步复制到定义的文件夹中。
           CryptoKeyPair keyPair = client.getCryptoSuite().createKeyPair();
           AssembleTransactionProcessor transactionProcessor = TransactionProcessorFactory.createAssembleTransactionProcessor(client, keyPair, "src/main/resources/abi/", "");
           // 创建调用交易函数的参数，此处为传入一个参数
           List<Object> params = new ArrayList<>();
           String name = "";
           params.add(name);
           // 调用HelloWorld合约，合约地址为helloWorldAddress， 调用函数名为『set』，函数参数类型为params
           TransactionResponse transactionResponse = transactionProcessor.sendTransactionAndGetResponseByContractLoader("TableTest", "0xf864ae752f297f0e4b4cb96b17092b3b44c1e22d", "select", params);
           List<Object> result = transactionResponse.getReturnObject();
           System.out.println(result);
//           if(result != null){
//               for (Object object : result) {
//                   System.out.println(object);
//               }
//           }
       }



    //使用Hash查询交易
    @Test
    public void queryTransactionByHash() throws Exception {
        //交易哈希
        String hash = "0x66a818686a222e43fa37ee00183b17e11d8900f3e0de427e2b2a1dd39a982fca";


        // 初始化BcosSDK对象
        BcosSDK sdk = BcosSDK.build(configFile);
        // 获取Client对象，此处传入的群组ID为1
        Client client = sdk.getClient(Integer.valueOf(1));
        // 构造AssembleTransactionProcessor对象，需要传入client对象，CryptoKeyPair对象和abi、binary文件存放的路径。abi和binary文件需要在上一步复制到定义的文件夹中。
        //此处使用的是随机生成密钥对
        //这里可以进行用户的加载。加载用户的密钥对
        CryptoKeyPair keyPair = client.getCryptoSuite().createKeyPair();
        AssembleTransactionProcessor transactionProcessor = TransactionProcessorFactory.createAssembleTransactionProcessor(client, keyPair, "src/main/resources/abi/", "src/main/resources/bin/");
        // 根据交易哈希查询交易回执
        BcosTransactionReceipt bcosReceipt = client.getTransactionReceipt(hash);
        TransactionReceipt receipt = bcosReceipt.getResult();
        //获取合约的abi文件的参数
        String api = transactionProcessor.getContractLoader().getABIByContractName("CropPesticideContract");
        //获取当前群组对应的密码学接口
        CryptoSuite cryptoSuite = client.getCryptoSuite();
        // 构造TransactionDecoderService实例，传入是否密钥类型参数。
        TransactionDecoderInterface decoder = new TransactionDecoderService(cryptoSuite);
        Map<String, List<List<Object>>> events =
                decoder.decodeEvents(api, receipt.getLogs());
        System.out.println("events:"+events);


        if (receipt != null) {
            System.out.println("Input: " + receipt.getInput());
            System.out.println("---------------------------------");
            System.out.println("Transaction Hash: " + receipt.getTransactionHash());
            System.out.println("Block Number: " + receipt.getBlockNumber());
            System.out.println("From: " + receipt.getFrom());
            System.out.println("To: " + receipt.getTo());
            System.out.println("Gas Used: " + receipt.getGasUsed());
            System.out.println("Status: " + receipt.getStatus());
            System.out.println("Output: " + receipt.getOutput());
            System.out.println("logs: " + receipt.getLogs());
            System.out.println("contractAddress: " + receipt.getContractAddress());
            
            // 解码output数据
            decodeOutputData(receipt.getOutput(), "insert");
        } else {
            System.out.println("Transaction not found for hash: " + hash);
        }

        //abi需要使用，bin不需要，穿空参
        String abi = transactionProcessor.getContractLoader().getABIByContractName("AreaProductTable");
        String bin = "";
        //解码input数据
        TransactionDecoder txDecodeSampleDecoder = buildTransactionDecoder(abi,bin);
        String jsonResult  = txDecodeSampleDecoder.decodeInputReturnJson(receipt.getInput());
        List<ResultEntity> listResult = txDecodeSampleDecoder.decodeInputReturnObject(receipt.getInput()).getResult();
        System.out.println("json => \n" + jsonResult );
        System.out.println("list => \n" + listResult);
//        // 也可以查询交易回执及证明信息
//        TransactionReceiptWithProof receiptWithProof = client.getTransactionReceiptByHashWithProof(hash);
//        if (receiptWithProof != null) {
//            ReceiptAndProof receiptAndProof = receiptWithProof.getTransactionReceiptWithProof();
//            System.out.println("Receipt Root: " + receiptAndProof.receiptRoot);
//            System.out.println("Receipt Proof: " + receiptAndProof.receiptProof);
//        }
    }
    
    // 解码output数据的方法
    private void decodeOutputData(String output, String functionName) {

    }
    
    // 专门用于解码你提到的ABI编码十六进制字符串的测试方法
    @Test
    public void decodeSpecificOutput() {}

    //测试保存账户
    @Test
    public void testSaveAccount() throws Exception {
// 创建非国密类型的CryptoSuite
        CryptoSuite cryptoSuite = new CryptoSuite(CryptoType.ECDSA_TYPE);
        // 随机生成非国密公私钥对
        CryptoKeyPair cryptoKeyPair = cryptoSuite.createKeyPair();
        // 获取账户地址
        String accountAddress = cryptoKeyPair.getAddress();
        System.out.println("账户地址：" + accountAddress);
        System.out.println("公钥：" + cryptoKeyPair.getHexPublicKey());
        System.out.println("私钥：" + cryptoKeyPair.getHexPrivateKey());
        System.out.println(cryptoSuite);
        //进行pem文件的本地保存
        cryptoKeyPair.storeKeyPairWithPemFormat();

        String basepath = "ncp-fisco/"; // 基础路径
        String objectName =  basepath;
//        FileInfo fileInfo = fileStorageService.of(file)
//                .setPath(objectName)
//                .upload();

    }
}